﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using ZilLion.Service.Core.Domain.EntityBase;
using ZilLion.Service.Core.Infrastructure.Base;
using ZilLion.Service.TaskPlatform.Controllers.StateContainer;
using ZilLion.Service.TaskPlatform.Domain.Entity;
using ZilLion.Service.TaskPlatform.Domain.Response;
using ZilLion.Service.TaskPlatform.Domain.Respository.Interface;

namespace ZilLion.Service.TaskPlatform.Controllers
{
    /// <summary>
    ///     作业调度平台节点
    /// </summary>
    [Route("Api/TaskPlatform/Node")]
    [AllowAnonymous]
    public class TaskNodeController : ZilLionControllerBase
    {
        private readonly INodeInfoRespository _nodeInfoRespository;
        private readonly INodePerformanceMonitorRespository _nodePerformanceMonitorRespository;
        private readonly INodeRunMonitorRespository _nodeRunMonitorRespository;
        private readonly NodeRunStateContainer _nodeRunStateContainer;
        private readonly TaskRunStateContainer _taskRunStateContainer;

        public TaskNodeController(INodeInfoRespository nodeInfoRespository,
            INodePerformanceMonitorRespository nodePerformanceMonitorRespository,
            INodeRunMonitorRespository nodeRunMonitorRespository, NodeRunStateContainer nodeRunStateContainer,
            TaskRunStateContainer taskRunStateContainer)
        {
            _nodeInfoRespository = nodeInfoRespository;
            _nodePerformanceMonitorRespository = nodePerformanceMonitorRespository;
            _nodeRunMonitorRespository = nodeRunMonitorRespository;
            _nodeRunStateContainer = nodeRunStateContainer;
            _taskRunStateContainer = taskRunStateContainer;
        }


        /// <summary>
        ///     节点心跳接口
        /// </summary>
        /// <returns></returns>
        [HttpPost("NodeHeartbeat")]
        public NodeServerResponse NodeHeartbeat([FromBody] NodeInfoEntity node)
        {
            if (node != null)
            {
                NodeRunMonitorInfoEntity state = null;
                if (!_nodeRunStateContainer.NodeRunStates.TryGetValue(node.Nodeid, out state))
                {
                    var nodeinfo = _nodeInfoRespository.GetNodeInfoByNodeId(node.Nodeid);
                    if (nodeinfo != null)
                    {
                        if (nodeinfo.Nodemac != node.Nodemac)
                            throw new Exception("节点ID,已被注册,请查看配置");
                    }
                    else
                    {
                        _nodeInfoRespository.AddNodInfo(node);
                    }
                    _nodeRunStateContainer.NodeRunStates.TryAdd(node.Nodeid,
                        new NodeRunMonitorInfoEntity
                        {
                            NodeId = node.Nodeid,
                            Nodename = nodeinfo?.Nodename?? node.Nodename??string.Empty,
                            Nodelastheartbeat = DateTime.Now,
                            NodeRunState = 1
                        });
                }
                else
                {
                    state.NodeRunState = 1;
                    state.Nodelastheartbeat = DateTime.Now;
                }
            }


            var process = Process.GetCurrentProcess();

            if (process != null)
                return new NodeServerResponse
                {
                    ServicePid = process?.Id ?? 0,
                    ServiceThreadsCount = process?.Threads?.Count ?? 0,
                    ServiceWorkingSet = process.WorkingSet64 / 1024 / 1024
                };


            return new NodeServerResponse
            {
                ServicePid = 0,
                ServiceThreadsCount = 0,
                ServiceWorkingSet = 0
            };
        }

        /// <summary>
        ///     节点性能监控信息接收接口
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        [Route("PerformanceMonitor")]
        [HttpPost]
        public ResponseBase PerformanceMonitor([FromBody] NodePerformanceMonitorEntity node)
        {

            return  new ResponseBase();
            //var nodeinfo = _nodeInfoRespository.GetNodeInfoByNodeId(node.Nodeid);
            //var runMonitorInfo = _nodeRunMonitorRespository.GetNodeMonitorInfoById(node.Nodeid);

            //if (nodeinfo != null && runMonitorInfo != null && runMonitorInfo.NodeRunState == 1)
            //    //当节点运行正常 才需要更新性能分析
            //{
            //    var oldentity = _nodePerformanceMonitorRespository.GetNodeMonitorInfoById(node.Nodeid);
            //    if (oldentity != null)
            //        _nodePerformanceMonitorRespository.MotifyPerformanceMonitorInfo(node);
            //    else
            //        _nodePerformanceMonitorRespository.AddPerformanceMonitorInfo(node);
            //    return new ResponseBase();
            //}
            //return new ResponseBase
            //{
            //    Errormodel =
            //        new WebErrorModel {Errtype = "nodenotfound", ErrMessage = "节点在管理平台状态异常，停止性能监控，请联系管理员查看节点状态！"}
            //};
        }

        /// <summary>
        ///     获取节点信息（包括性能信息，心跳信息，节点本身信息）
        /// </summary>
        /// <returns></returns>
        [Route("NodeAllInfo")]
        [HttpGet]
        public NodeInfoResponse GetNodeAllInfo()
        {
            var nodeInfos = new List<NodeAllInfo>();
            var nodes = _nodeInfoRespository.GetNodeInfoEntities();
            foreach (var node in nodes)
            {
                var nodeAllInfo = new NodeAllInfo();
                var nodeRunMonitorInfo = _nodeRunMonitorRespository.GetNodeMonitorInfoById(node.Nodeid);
                var nodePerformanceMonitor = _nodePerformanceMonitorRespository.GetNodeMonitorInfoById(node.Nodeid);
                nodeAllInfo.NodeInfo = node;
                nodeAllInfo.NodeRunMonitorInfo = nodeRunMonitorInfo;
                nodeAllInfo.NodePerformanceMonitor = nodePerformanceMonitor;
                nodeInfos.Add(nodeAllInfo);
            }

            return new NodeInfoResponse {NodeInfos = nodeInfos};
        }

        /// <summary>
        ///     设置节点不可用
        /// </summary>
        /// <param name="nodeid"></param>
        /// <returns></returns>
        [Route("StopNode/{nodeid}")]
        [HttpGet]
        public ResponseBase SetNodeStop(string nodeid)
        {
            var node = _nodeRunMonitorRespository.GetNodeMonitorInfoById(nodeid);
            node.NodeRunState = 0;
            _nodeRunMonitorRespository.MotifyPerformanceMonitorInfo(node);
            return new ResponseBase();
        }

        [Route("SaveNodeInfo")]
        [HttpPost]
        public ResponseBase SetNodeStop([FromBody] NodeInfoEntity entity)
        {
            _nodeInfoRespository.MotifyNodeInfo(entity);
            return new ResponseBase();
        }

        [Route("GetNodeMonitorInfos")]
        [HttpGet]
        public NodeMonitorResponse GetNodeMonitorInfos()
        {
            var nodes = _nodeRunStateContainer.NodeRunStates.Values;
            IList<NodeMonitorDto> nodeMonitorInfos = new List<NodeMonitorDto>();
            foreach (var node in nodes)
            {
                var dto = new NodeMonitorDto
                {
                    NodeId = node.NodeId,
                    Nodelastheartbeat = node.Nodelastheartbeat,
                    NodeRunState = node.NodeRunState
                };

                ConcurrentDictionary<string, TaskStateEntity> statedic;
                if (_taskRunStateContainer.TaskStates.TryGetValue(node.NodeId, out statedic))
                    dto.Tasks = statedic?.Values.ToList();

                nodeMonitorInfos.Add(dto);
            }
            return new NodeMonitorResponse {NodeMonitorInfos = nodeMonitorInfos};
        }
    }
}